package com.system.core.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;

import com.system.core.conf.dto.ExceptionCommonRsp;

import io.swagger.v3.oas.annotations.Hidden;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;

@Controller
@Slf4j
@Hidden
public class ExceptionController implements ErrorController {

	private static final String ERROR_PATH = "/error";
	private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	@Resource
    private ErrorAttributes errorAttributes;

    /**
     * web页面异常请求处理
     * @param request
     * @return
     */
    @GetMapping(value = ERROR_PATH, produces = MediaType.TEXT_HTML_VALUE)
    public String handlePageError(HttpServletRequest request,ModelMap model) {
        Integer statusCode = getStatus(request);
        WebRequest webRequest = new ServletWebRequest(request);
        Map<String, Object> body = this.errorAttributes.getErrorAttributes(webRequest, ErrorAttributeOptions.defaults());
        body.forEach((key,value)->{
        	if(value instanceof Date) {
        		model.put(key, format.format(value));
        	} else {
        		model.put(key, value);
        	}
        });
        switch (statusCode) {
            case 404:
            	log.info("404异常跳转");
                return "error/404";
            case 403:
            	log.info("403异常跳转");
                return "error/403";
            case 500:
            	log.info("500异常跳转");
                return "error/500";
            default:
            	log.info("默认异常跳转");
                return "error/404";
        }
    }

    /**
     * 其他异常请求处理，例如：contentType：application/json等
     * @param request
     * @return
     */
    @PostMapping(ERROR_PATH)
	@ResponseBody
    public ExceptionCommonRsp handleAllError(HttpServletRequest request) {
        WebRequest webRequest = new ServletWebRequest(request);
        Integer statusCode = getStatus(request);
        Map<String, Object> body = this.errorAttributes.getErrorAttributes(webRequest, ErrorAttributeOptions.defaults());
        body.put("status", statusCode);
        ExceptionCommonRsp response = ExceptionCommonRsp.builder()
        		.code(String.valueOf(statusCode))
        		.message(body.get("error").toString())
        		.requestPath(body.get("path").toString())
        		.causeErrorType("errorPage")
        		.build();
        return response;
    }

    /**
     * 获取状态码
     * @param request
     * @return
     */
    public Integer getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("jakarta.servlet.error.status_code");
        if (statusCode == null) {
            return 500;
        }
        return statusCode;
    }

    /**
     * Spring 默认错误页路径
     * @return
     */
    public String getErrorPath() {
        return ERROR_PATH;
    }
}
